/*
 * Log.cpp
 *
 *  Created on: 12/10/2012
 */

#include "Log.h"

Log* Log::instance = NULL;
const long long Log::microsegundosInicial = getMicrosegundos();
const string Log::nombreArchivo = string(PATH_LOG) + getFecha() + getHora() + string(EXTENSION_LOG);

Log::Log()
 : modoDebug (false),
   logFile ((char*) nombreArchivo.c_str()){

	cout.setf(ios::fixed);
	cout.precision(PRECISION_SEGUNDOS);
}

Log* Log::getInstance() {
	if (instance == NULL)
		instance = new Log();
	return instance;
}

void Log::destruir() {
	if (instance != NULL) {
		Log::getInstance()->loguear("Log: destruido.");
		delete (instance);
		instance = NULL;
	}
}

void Log::setModoDebug(bool modoDebug){
	this->modoDebug = modoDebug;
}

/**
 * Agrega al mensaje el pid el proceso que está escribiendo y
 * los segundos desde que comenzó la ejecución.
 */
string Log::adecuarMensaje(string mensaje){
	stringstream s;
	s.setf(ios::fixed);
	s.precision(PRECISION_SEGUNDOS);
	s << "Proceso: "<< getpid() << " " << this->getSegundosDesdeComienzo() << "s: " << mensaje << endl;
	string completo(s.str());
	return completo;
}

void Log::loguear(string mensaje){
	if (this->modoDebug){
		if (logFile.tomarLock() == 0) {
			string cadena = this->adecuarMensaje(mensaje);
			if (logFile.escribir(cadena.c_str(), strlen(cadena.c_str())) == -1) {
				cerr << "Proceso: " << getpid() << ": Ha ocurrido un error al escibir el mensaje: \""
						<< mensaje << "\"." << endl;
			}
			logFile.liberarLock();
		}
		else {
			cerr << "Proceso: " << getpid() << ": Error al abrir el archivo: " << nombreArchivo
				<< ". Mensaje: \"" << mensaje << "\"." << endl;
		}
	}
}

void Log::imprimir(string mensaje){
	cout << this->getSegundosDesdeComienzo() <<  "s: " << mensaje << endl;
}

float Log::getSegundosDesdeComienzo(){
	long long microsegundos = getMicrosegundos() - microsegundosInicial;
	return (float) microsegundos / 1000000;
}
